namespace CRM_Perf_BenchMark
{
    using System;
    using System.Collections.Generic;
    using Microsoft.VisualStudio.TestTools.WebTesting;
    using System.Net;
    using System.Text;
    using System.Xml;
    
    /// <summary>
    /// 1. Start at Sales tab
    /// 2. Click on Contacts
    /// 3. Click New button
    /// 4. Add relevant data (first and lastname)
    /// 5. Click on Custom Attributes tab and fill custom data
    /// 5. Click Save & Close
    /// </summary>

    public class CreateNewContactWithCustomAttributes : CrmWebTest
    {
        public void CreateNewContactWithCustomAttributes_PreWebTest(object sender, PreWebTestEventArgs e)
        {
            EntityRequest er = new EntityRequest();
            er.Type = EntityNames.Users;
            er.ReturnAs = EntityNames.Users;
            er.ParentID = EntityManager.Instance.OrgId;

            System.Collections.Hashtable userProps = new System.Collections.Hashtable();
            if (e.WebTest.Context.ContainsKey("UserRole"))
            {
                userProps.Add("role", e.WebTest.Context["UserRole"]);
                er.Props = userProps;
            }
                        
            System.Collections.Hashtable Entities = EntityManager.Instance.GetEntities(er);

            user = (CRMEntity)Entities[EntityNames.Users];

            crmServer = user["CrmServer"];
            tokenKey = EntityManager.Instance.ReadTokenKey(user["organizationid"]);

            orgId = new Guid(user["organizationid"]);
            ownerId = new Guid(user["systemuserid"]);

            e.WebTest.UserName = user["domainName"];
            e.WebTest.Password = user["userpassword"];            
        }

        public void CreateNewContactWithCustomAttributes_PostWebTest(object sender, PostWebTestEventArgs e)
        {
            try
            {
                if (newContId != null)
                {
                    newContId = new Guid(newContId).ToString();
                    Guid g = EntityManager.Instance.GetOwnerGuid(new Guid(user[EntityIDNames.User]), new Guid(user["OrganizationId"]));
                    EntityManager.Instance.AddEntity(EntityNames.Contacts, g, new string[] { "OwningUser", "ContactID", "EntityManagerOwningUser" }, new string[] { user["systemuserid"], newContId, g.ToString() });
                }
            }
            catch (System.FormatException fe)
            {
                System.Diagnostics.Trace.WriteLine("Failed to convert bogus data into Guid. " + fe.ToString());
            }
            finally
            {
                EntityManager.Instance.FreeEntity(user);
            }
        }

        private void NewContact_ValidateResponse(object sender, ValidationEventArgs e)
        {
            string ID = null;

            int idIdx = e.Response.BodyString.IndexOf(newIdMarker);
            ID = e.Response.BodyString.Substring(idIdx + (CreateNewContactWithCustomAttributes.newIdMarker.Length), 36);
            try
            {
                ID = new Guid(ID).ToString();
            }
            catch (System.FormatException fe)
            {
                System.Diagnostics.Trace.WriteLine("Format exception: " + fe.ToString());
                e.IsValid = false;
                return;
            }

            e.IsValid = true;
        }

        public CreateNewContactWithCustomAttributes()
        {
            WebRequest.RegisterPrefix("crm", new crmRequestFactory());
            gridXml = GridXmlHelper.ContactPageViewRefresh(-1, contactRefreshView, null);

            this.Proxy = null;
            PreWebTest += new EventHandler<PreWebTestEventArgs>(CreateNewContactWithCustomAttributes_PreWebTest);
            PostWebTest += new EventHandler<PostWebTestEventArgs>(CreateNewContactWithCustomAttributes_PostWebTest);
        }

        public override IEnumerator<WebTestRequest> GetRequestEnumerator()
        {
            this.BeginTransaction("NavContactHomepage");

            _root_homepage_aspx hp = new _root_homepage_aspx(user);
            hp.etc = 2;
            yield return (hp);

            this.EndTransaction("NavContactHomepage");

            this.BeginTransaction("CreateContactWithCustomAttributes");

            sfa_conts_edit_aspx dp = new sfa_conts_edit_aspx(user);
            yield return (dp);

            referer = dp.lastResponse.ResponseUri.AbsoluteUri;

            _forms_FormScript_js_aspx formScript = new _forms_FormScript_js_aspx(user);
            formScript.etc = 2;
            formScript.FormType = "main";
            formScript.FormName = "crmForm";
            headerItem = new WebTestRequestHeader("referer", referer);
            formScript.Headers.Add(headerItem);
            yield return (formScript);

            // if the Help and Assistance Pane is on and the user tabs through the fields of the Contact
            // detail pane, they'll hit this (heavy) request when the tab into the 
            // primay contact field.
            if (ConfigSettings.Default.HelpAndAssistancePaneOn == "true")
            {
                //TODO: implement for Contact.  See CreateNewAccount for reference.
            }

            _controls_number_formatNumber_xsl formatNum = new _controls_number_formatNumber_xsl(crmServer);            
            yield return (formatNum);

            dp = new sfa_conts_edit_aspx(user);
            firstname = Utils.GetRandomString(5, 10);
            lastname = Utils.GetRandomString(5, 10);

            dp.crmFormSubmitXml = EntityXmlHelper.GetCreateContactWithCustomAttributesXml(ownerId, 8, lastname, firstname);
            dp.crmFormSubmitMode = 1;
            dp.crmFormUserModified = true;
            dp.crmFormSubmitObjectType = 2;
            dp.crmFormSubmitSecurity = 852023;
            dp.crmFormSubmitOnline = 1;
            rpcInfo = Utils.GenerateWRPCToken(sfa_conts_edit_aspx.url, user, tokenKey);
            dp.CRMWRPCToken = rpcInfo.token;
            dp.CRMWRPCTokenTimeStamp = rpcInfo.timeStamp;
            dp.ValidateResponse += this.NewContact_ValidateResponse;
            yield return (dp);

            //get the newly created Contact id out of the post reply
            int idIdx = dp.lastResponse.BodyString.IndexOf(newIdMarker);
            //Force casting it through a GUID ensures that the test actually worked. We'll get a format exception if the create didn't work.
            string tempNewContId = dp.lastResponse.BodyString.Substring(idIdx + (CreateNewContactWithCustomAttributes.newIdMarker.Length), 36);
            newContId = new Guid(tempNewContId).ToString();

            AppGridWebService.AppGridWebService agws = new AppGridWebService.AppGridWebService();
            WebTestRequest wtrRefresh = null;
            try { agws.Refresh(gridXml); }
            catch (crmException x)
            {
                wtrRefresh = x.wtr;
                wtrRefresh.Url = Utils.ReplaceServerName(wtrRefresh.Url, user);

                string urlPath = wtrRefresh.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtrRefresh.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtrRefresh.Headers.Add(headerItem);
                wtrRefresh.Method = "Post";
            }
            yield return (wtrRefresh);

            this.EndTransaction("CreateContactWithCustomAttributes");
        }

        private const string newIdMarker = @"separator + ""id=";
        private CRMEntity user;
        private string newContId = null;
        private string gridXml;
        private string crmServer;
        private string tokenKey;
        private static string contactRefreshView = "00000000-0000-0000-00AA-000010001003";

        private Guid orgId;
        private string firstname;
        private string lastname;
        private Guid ownerId;
        private string referer;
        private WRPCInfo rpcInfo;
        private WebTestRequestHeader headerItem;
    }
}